package com.msh.artascope.devcloud.service.client;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.msh.artascope.devcloud.client.po.GitlabConfigPo;
import com.msh.artascope.devcloud.service.util.RestTemplateUtil;
import com.msh.frame.client.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;


@Slf4j
@Service
public class GiteaClient {
    private RestTemplate restTemplate;

    public GiteaClient() {
        this.restTemplate = RestTemplateUtil.newNoCheckSslRestTemplate();
    }

    private static final String GET_PROJECT_INFO_FORMAT = "%s/api/v1/repos/%s/%s";
    private static final String GET_PROJECT_INFO_BY_ID_FORMAT = "%s/api/v1/repositories/%s";
    private static final String GET_PROJECT_COMMIT_LIST_FORMAT = "%s/api/v1/repos/%s/%s/commits";



    public Long getProjectId(GitlabConfigPo po, String gitUrl){
        try {
            String targetData = gitUrl.split(":")[1];
            String ownerWithNameString = targetData.substring(0,targetData.lastIndexOf("."));
            String[] ownerWithNames = ownerWithNameString.split("/");
            JSONObject projectInfo = getProjectInfo(po, ownerWithNames[0], ownerWithNames[1]);
            if(null == projectInfo){
                return null;
            }
            return projectInfo.getLong("id");
        } catch (Exception e) {
            log.error("GiteaClient getProjectId error", e);
            throw BizException.build("获取git项目id失败");
        }
    }

    public String getLastCommitId(GitlabConfigPo po, Long projectId, String branch){
        JSONObject projectInfo = getProjectInfo(po, projectId);
        if(null == projectInfo){
            return null;
        }
        String fullName = projectInfo.getString("full_name");
        if(null == fullName){
            return null;
        }
        String[] split = fullName.split("/");
        JSONObject projectLastCommit = getProjectLastCommit(po, split[0], split[1], branch);
        if(null == projectLastCommit){
            return null;
        }
        return projectLastCommit.getString("sha");
    }

    private JSONObject getProjectInfo(GitlabConfigPo po, String owner, String name){
        try {
            String url = String.format(GET_PROJECT_INFO_FORMAT, po.getAddress(), owner, name);
            return restTemplate
                    .exchange(url, HttpMethod.GET, buildHttpEntity(po), JSONObject.class).getBody();
        }catch (BizException be){
            throw be;
        }catch (Exception e){
            log.error("调用git接口失败: getProjectInfo. {}, {}, {}", po.getAddress(), owner, name, e);
            throw new BizException("调用git接口失败");
        }
    }

    private JSONObject getProjectInfo(GitlabConfigPo po, Long projectId){
        try {
            String url = String.format(GET_PROJECT_INFO_BY_ID_FORMAT, po.getAddress(), projectId);
            return restTemplate
                    .exchange(url, HttpMethod.GET, buildHttpEntity(po), JSONObject.class).getBody();
        }catch (BizException be){
            throw be;
        }catch (Exception e){
            log.error("调用git接口失败: getProjectInfo. {}, {}, {}", po.getAddress(), projectId, e);
            throw new BizException("调用git接口失败");
        }
    }

    private JSONObject getProjectLastCommit(GitlabConfigPo po, String owner, String name, String branch){
        try {
            String url = String.format(GET_PROJECT_COMMIT_LIST_FORMAT, po.getAddress(), owner, name);
            url = url + "?page=1&limit=1&sha=" +branch;
            JSONArray jsonArray = restTemplate
                    .exchange(url, HttpMethod.GET, buildHttpEntity(po), JSONArray.class).getBody();
            if(CollectionUtils.isEmpty(jsonArray)){
                return null;
            }
            return jsonArray.getJSONObject(0);
        }catch (BizException be){
            throw be;
        }catch (Exception e){
            log.error("调用git接口失败: getProjectLastCommit. {}, {}, {}", po.getAddress(), owner, name, e);
            throw new BizException("调用git接口失败");
        }
    }


    private HttpEntity<String> buildHttpEntity(GitlabConfigPo po){
        return buildHttpEntity(po, null);
    }

    private HttpEntity<String> buildHttpEntity(GitlabConfigPo po, String body){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if(!StringUtils.isEmpty(po.getToken())){
            headers.add("Authorization", "token " + po.getToken());
        }
        return new HttpEntity<String>(body, headers);
    }
}
